local ExcelMapConf = require("excel.Map")
local Lang = require("common.Lang")
local Map = require("core.Map")
local map_mgr = _G.map_mgr
local MapEx = require("core.MapEx")
local Msg = require("core.Msg")
local Obj = require("core.Obj")
local ObjHuman = require("core.ObjHuman")
local ObjMonster = require("core.ObjMonster")
local ObjCollect = require("core.ObjCollect")
local ObjDisplay = require("core.ObjDisplay")
local Status = require("scene.Status")
local Timer = require("core.Timer")
local Config = require("Config")
local Copy  = require("copy.CopyL")
local CopyAim = require("copy.Aim")
local Skill = require("skill.Skill")
local ObjSkill = require("core.ObjSkill")
local ObjNpc = require("core.ObjNpc")
local EffectLogic = require("scene.EffectLogic")
local CopyCallback = require("copy.CallbackL")
local Buffer = require("buffer.Buffer")
local ObjBuf = require("core.ObjBuf")
local ExcelMonster = require("excel.Monster")
local Broadcast = require("broadcast.Broadcast")
local TaskLogic = require("task.TaskLogic")
local Pata = require("copy.Pata")
local ExcelLevelReward = require("excel.LevelReward")

--local Util = require("common.Util")
local condition_check_n = {}
local action_set_n = {}
data = {}

ban = ban or {}
create_time = create_time or {}
event_cnt = event_cnt or {}
event_time = event_time or {}
n = n or {}
wake_up_time = wake_up_time or {}
piaohua = piaohua or {}

reborn_monster_die_time = reborn_monster_die_time or {}
has_err = has_err or {}


local action = {}
local condition = {}

function action.accept_aim(aim_id)
	local scene_id = data.scene_id
	local copyID = Copy.sceneID2CopyID[scene_id]	-- 场景ID对应副本ID
	local roomID = Copy.sceneID2Room[scene_id]		-- 场景ID对应房间号
	if copyID and roomID then 
		CopyAim.aimDoAccept(aim_id, copyID, roomID)
	end
end

function action.add_display(area_id, body_id, name)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	for i = 1, #list_rect do
		local rect = list_rect[i]
		local display = ObjDisplay.create(area_id, body_id)
		display.name = name
		local mm = Msg.gc.GC_BEFORE_OBJ_APPEAR
		mm.obj_id = display.id
		mm.cmd = 2
		if Obj.scenes[scene_id] then
			Obj.sendArea(mm, scene_id, (rect[1] + rect[3]) / 2, (rect[2] + rect[4]) / 2)
		end
		Obj.enterScene(display, scene_id, (rect[1] + rect[3]) / 2, (rect[2] + rect[4]) / 2, true)
	end
end

function action.add_display_group(group, name)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	if not MapEx[map_id].display then
		assert(nil, map_id .. " " .. group)
	end
	if not MapEx[map_id].display[group] then
		assert(nil, map_id .. " " .. group)
	end
	for _, v in ipairs(MapEx[map_id].display[group]) do
		local display = ObjDisplay.create(area_id, v[1])
		display.name = name
		display.group = group
		local mm = Msg.gc.GC_BEFORE_OBJ_APPEAR
		mm.obj_id = display.id
		mm.cmd = 2
		if Obj.scenes[scene_id] then
			Obj.sendArea(mm, scene_id, v[2], v[3])
		end
		Obj.enterScene(display, scene_id, v[2], v[3], true)
	end
end


function action.ban_add(area_id)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	ban[scene_id] = ban[scene_id] or {}
	local t = ban[scene_id]
	for _, v in ipairs(t) do
		if v == area_id then
--		  print("ban_add some times error :area_id: "..area_id)
      return
		end
	end
	t[#t + 1] = area_id
	local list_rect = Map.getRects(map_id, area_id)
	local mm = Msg.gc.GC_BAN_ADD
	mm.rect[0] = #list_rect
	for i = 1, mm.rect[0] do
		local left = mm.rect[i]
		local right = list_rect[i]
		left.x1 = right[1]
		left.y1 = right[2]
		left.x2 = right[3]
		left.y2 = right[4]
	end
	Obj.sendScene(mm, scene_id)
end

function action.ban_del(area_id)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	local t = ban[scene_id]
	if not t then
		return
	end
	local ac
	for k, v in ipairs(t) do
		if v == area_id then
			ac = true
			t[k] = t[#t]
			t[#t] = nil
			break
		end
	end
	if not ac then
		--assert()
		return
	end
	if not t[1] then
		ban[scene_id] = nil
	end
	local list_rect = Map.getRects(map_id, area_id)
	local mm = Msg.gc.GC_BAN_DEL
	mm.rect[0] = #list_rect
	for i = 1, mm.rect[0] do
		local left = mm.rect[i]
		local right = list_rect[i]
		left.x1 = right[1]
		left.y1 = right[2]
		left.x2 = right[3]
		left.y2 = right[4]
	end
	Obj.sendScene(mm, scene_id)
end

function action.buf(area_id, buf_id, target_type)
	local scene_id = data.scene_id
	for _, o in pairs(Obj.scenes[scene_id]) do
		if not o.hide and (o.obj_type == Obj.TYPE_HUMAN and (target_type == 1 or target_type == 3) or o.obj_type == Obj.TYPE_MONSTER and (target_type == 2 or target_type == 3)) then
			if Map.is_in_area_id(Map.scene_id_to_map_id[scene_id], o.x, o.y, area_id) then
				Buffer.add(buf_id, o, ObjBuf.create())
			end
		end
	end
end

function action.sex_buf(area_id, buflist, sex)
  local scene_id = data.scene_id
  for _, o in pairs(Obj.scenes[scene_id]) do
    if not o.hide and o.obj_type == Obj.TYPE_HUMAN and o.db.sex == sex then
      if Map.is_in_area_id(Map.scene_id_to_map_id[scene_id], o.x, o.y, area_id) then
        for buf_id in pairs(buflist) do
          Buffer.add(buf_id, o, ObjBuf.create())
        end
      end
    end
  end  
end

--给指定怪物ID的怪物加buf
function action.add_monster_buf(monster_id, buf_id_list)
	local scene_id = data.scene_id
	for _, o in pairs(Obj.scenes[scene_id]) do
		if o.obj_type == Obj.TYPE_MONSTER and o.monster_id == monster_id then
				for i=1, #buf_id_list do
					local buf_id = buf_id_list[i]
					Buffer.add(buf_id, o, ObjBuf.create())
				end
		end
	end
end
--删除指定怪物的指定BUFF
function action.del_monster_buf(monster_id, buf_id_list)
  local scene_id = data.scene_id
  for _, o in pairs(Obj.scenes[scene_id]) do
    if o.obj_type == Obj.TYPE_MONSTER and o.monster_id == monster_id then
        for i=1, #buf_id_list do
          local buf_id = buf_id_list[i]
          Buffer.removeID(buf_id, o)
        end
    end
  end
end

function action.change_ai_bag(group, ai_bag_ids)
	for _, monster in pairs(Obj.scenes[data.scene_id]) do
		if monster.monster_id and monster.group == group then
			monster.ai_bag = ai_bag_ids
			monster.last_ai_id = nil
		end
	end
end

function action.change_ai_bag_monster_id(monster_id, ai_bag_ids)
  for _, monster in pairs(Obj.scenes[data.scene_id]) do
    if monster.monster_id == monster_id then
      monster.ai_bag = ai_bag_ids
      monster.last_ai_id = nil
    end
  end
end

function action.change_collect_body_id(collect_id, body_id)
	local scene_id = data.scene_id
	for _, v in pairs(Obj.scenes[scene_id]) do
		if v.collect_id == collect_id then
			v.body_id = body_id
			v.body_bone = 0
			local mm = Msg.gc.GC_COLLECT_COLLECTED_NOTIFY
			mm.objID = v.id
			mm.bodyID = body_id
			Obj.sendArea(mm, scene_id, v.x, v.y)
			break
		end
	end
end

function action.cl_ai(tb_ai)
	local cnt = event_cnt[data.scene_id]
	if type(tb_ai) == "number" then	
		cnt[tb_ai] = nil
	else
		for _, v in ipairs(tb_ai) do
			cnt[v] = nil
		end
	end
end

function action.cl_buf(area_id, buf_id, target_type)
	local scene_id = data.scene_id
	for _, o in pairs(Obj.scenes[scene_id]) do
		if not o.hide and (o.obj_type == Obj.TYPE_HUMAN and (target_type == 1 or target_type == 3) or o.obj_type == Obj.TYPE_MONSTER and (target_type == 2 or target_type == 3)) then
			if Map.is_in_area_id(Map.scene_id_to_map_id[scene_id], o.x, o.y, area_id) then
				for _, v in ipairs(buf_id) do
					Buffer.removeID(v, o)
				end
			end
		end
	end
end

function action.countdown(num, type)
	local mm = Msg.gc.GC_COUNTDOWN
	mm.num = num
	mm.type = type or 0
	Obj.sendScene(mm, data.scene_id)
end

function action.delcountdown()
  local mm = Msg.gc.GC_DEL_COUNTDOWN
  Obj.sendScene(mm, data.scene_id)
end

function action.del_all_monster()
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.monster_id and ExcelMonster.monster[v.monster_id].camps == "enemy" then
			v.hp = 0
			v.dieTime = 0
		end
	end
end
function action.del_monster_group(group)
  if not group then
    assert()
  end
  for _, v in pairs(Obj.scenes[data.scene_id]) do
    if v.monster_id and v.group == group then
        ObjMonster.destroy(v)
    end
  end
end

function action.del_collect_group(group)
	if not group then
		assert()
	end
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.collect_id and v.group == group then
			ObjCollect.destroy(v)
		end
	end
end

function action.del_collect_id(collect_id)
	if not collect_id then
		assert()
	end
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.collect_id == collect_id then
			ObjCollect.destroy(v)
		end
	end
end

function action.del_display(area_id, body_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.obj_type == Obj.TYPE_DISPLAY and v.area_id == area_id and v.body_id == body_id then
			v.die = 1
			ObjDisplay.destroy(v)
		end
	end
end

function action.del_display_group(group)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.obj_type == Obj.TYPE_DISPLAY and v.group == group then
			ObjDisplay.destroy(v)
		end
	end
end

function action.del_monster_id(tb)
	local hash = {}
	for k, v in ipairs(tb) do
		hash[v] = true
	end
	for k, v in pairs(Obj.scenes[data.scene_id]) do
		local monster_id = v.monster_id
		if hash[monster_id] then
			ObjMonster.destroy(v)
		end
	end
end

function action.del_npc_group(group)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	for _, v in pairs(Obj.scenes[scene_id]) do
		if v.npc_id then
			for _, vv in ipairs(MapEx[map_id].npc[group]) do
				if vv[1] == v.npc_id then
					Obj.destroy(v)
				end
			end
		end
	end
end

function action.exp(area_id, level_reward_id)
	local cf = ExcelLevelReward[level_reward_id]
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	for _, v in pairs(Obj.scenes_fds[scene_id]) do
		if Map.is_in_area_id(map_id, v.x, v.y, area_id) then
			local exp = cf[v.db.lv].exp
			if 0 < exp then
				ObjHuman.addExp(v, exp)
				CopyCallback.onActionAddExp(v, scene_id, exp)
			end
			local money = cf[v.db.lv].money
			if money and 0 < money then
				ObjHuman.addYinliang(v, money, "scene_event")
			end
		end
	end
end

function action.finish_aim(aim_id)
--	print("finish_aim id:", aim_id)

	local scene_id = data.scene_id
	local copyID = Copy.sceneID2CopyID[scene_id]	-- 场景ID对应副本ID
	local roomID = Copy.sceneID2Room[scene_id]		-- 场景ID对应房间号
	if copyID and roomID then 
		CopyAim.aimDoFinish(aim_id, copyID, roomID)
	end
end

function action.finish_task(taskID)
  for _, human in pairs(Obj.scenes[data.scene_id]) do
    if human.obj_type == Obj.TYPE_HUMAN then
       TaskLogic.sceneFinishTask(human, taskID)
    end
  end
end

function action.fail_aim(aim_id)
	local scene_id = data.scene_id
	local copyID = Copy.sceneID2CopyID[scene_id]	-- 场景ID对应副本ID
	local roomID = Copy.sceneID2Room[scene_id]		-- 场景ID对应房间号
	if copyID and roomID then 
		CopyAim.aimDoFail(aim_id, copyID, roomID)
	end
end

function action.fail_aim_exit(aim_id)
  local scene_id = data.scene_id
  local copyID = Copy.sceneID2CopyID[scene_id]  -- 场景ID对应副本ID
  local roomID = Copy.sceneID2Room[scene_id]    -- 场景ID对应房间号
  if copyID and roomID then 
    CopyAim.aimDoFail(aim_id, copyID, roomID, true)
  end
end

function action.jump(area_id, map_id, x, y)
	local scene_id = data.scene_id
	local local_map_id = Map.scene_id_to_map_id[scene_id]
	local isPVP = ExcelMapConf.scene[map_id].isPVP
	local levelLimit = ExcelMapConf.scene[map_id].lvLimit
	local msg = nil
	if isPVP == 1 then
		msg = Msg.gc.GC_ENTER_PVP_WARNING
		msg.mapID = map_id
		msg.areaID = area_id
		msg.level = levelLimit
	end
	
	for _, o in pairs(Obj.scenes[scene_id]) do
		if o.obj_type == Obj.TYPE_HUMAN and o.fd and not o.hide  then
			if Map.is_in_area_id(local_map_id, o.x, o.y, area_id) then
				if isPVP == 1 and false then
					-- 下发通知
					Msg.send(msg, o.fd)
				else
					if o.db.lv >= levelLimit then
						ObjHuman.enterMap(o, map_id, x, y)
					else
						if o.jump_tip_x ~= o.x or o.jump_tip_y ~= o.y then
							o.jump_tip_x = o.x
							o.jump_tip_y = o.y
							local mm = Msg.gc.GC_ENTER_MAP_ERR
							mm.err = "达到" .. levelLimit .. "级方可进入"
							Msg.send(mm, o.fd)
						end
					end
				end
			end
		end
	end
end

function action.jump_local(area_id, x, y, way)
	if not way then
		assert(nil, jump_local)
	end
	local scene_id = data.scene_id
	for _, o in pairs(Obj.scenes[scene_id]) do
		if o.obj_type == Obj.TYPE_HUMAN and not o.hide then
			if Map.is_in_area_id(Map.scene_id_to_map_id[scene_id], o.x, o.y, area_id) then
				Status.onJump(o)
				Obj.jump(o, x, y, way == 0 and Msg.gc.GC_JUMP or way == 1 and Msg.gc.GC_CHONG_FENG or way == 2 and Msg.gc.GC_NPC_JUMP)
				local pet = Obj.getObj(o.fight_pet_id, o.fight_pet_uid)
			  if pet then
				  Obj.jump(pet, x, y, Msg.gc.GC_JUMP)
			  end
			end
		end
	end
end

function action.jump_camps(area_id, x, y, camps)
	if not camps then
		assert(nil, jump_camp)
	end
	local scene_id = data.scene_id
	for _, o in pairs(Obj.scenes[scene_id]) do
		if o.obj_type == Obj.TYPE_HUMAN and not o.hide and o.camps == camps then
			if Map.is_in_area_id(Map.scene_id_to_map_id[scene_id], o.x, o.y, area_id) then
				Status.onJump(o)
				Obj.jump(o, x, y, Msg.gc.GC_JUMP)
				local pet = Obj.getObj(o.fight_pet_id, o.fight_pet_uid)
			    if pet then
			        Obj.jump(pet, x, y, Msg.gc.GC_JUMP)
			    end
			end
		end
	end
end

-- 本地图跳转，多个目标点
function action.jump_rand(area_id, poslist, way)
  if not way then
    assert(nil, jump_local)
  end
  
  local scene_id = data.scene_id
  local  x,y
  local  i = math.random(1, #poslist)
  for _, o in pairs(Obj.scenes[scene_id]) do
    if o.obj_type == Obj.TYPE_HUMAN and not o.hide then
      i = i + 1
      if i >= #poslist then
          i = 1
      end
      x = poslist[i][1]
      y = poslist[i][2]
      if Map.is_in_area_id(Map.scene_id_to_map_id[scene_id], o.x, o.y, area_id) then
        Status.onJump(o)
        Obj.jump(o, x, y, way == 0 and Msg.gc.GC_JUMP or way == 1 and Msg.gc.GC_CHONG_FENG or way == 2 and Msg.gc.GC_NPC_JUMP)
      end
      local pet = Obj.getObj(o.fight_pet_id, o.fight_pet_uid)
      if pet then
        Obj.jump(pet, x, y, Msg.gc.GC_JUMP)
      end
    end
  end
end

function action.n_clear()
	n[data.scene_id] = nil
	CopyCallback.onSceneNChange(scene_id)
end

function action.piaohua(area_id, cmd, effect_id)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	local mm = Msg.gc.GC_PIAO_HUA
	mm.cmd = cmd
	mm.effect_id = effect_id
	if area_id == -1 then
		mm.x = 0
		mm.y = 0
		mm.half_w = 0
		mm.half_h = 0
		Obj.sendScene(mm, scene_id)
	else
		for _, v in ipairs(list_rect) do
			mm.x = (v[1] + v[3]) / 2
			mm.y = (v[2] + v[4]) / 2
			mm.half_w = (v[3] - v[1]) / 2
			mm.half_h = (v[4] - v[2]) / 2
			Obj.sendScene(mm, scene_id)
		end
	end
	if piaohua[scene_id] then
		assert()
	end
	piaohua[scene_id] = {area_id, cmd, effect_id}
end

function action.new_collect(area_id, cap, collect_tb)
	local sum = 0
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.collect_id and v.area_id == area_id then
			sum = sum + 1
			if cap <= sum then			 
				return
			end
		end
	end

	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	for i = 1, cap - sum do
		local collect_id = collect_tb[math.random(1, #collect_tb)]
		local collect = ObjCollect.create(collect_id)
		local rect = list_rect[math.random(1, #list_rect)]
		collect.area_id = area_id
		ObjCollect.enterScene(collect, data.scene_id, math.random(rect[1], rect[3]), math.random(rect[2], rect[4]))
	end
end

local list_collect = {}
function action.new_collect_group(group)
	local lenCollect = 0
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	if not MapEx[map_id].collect[group] then
		assert(nil, ""..map_id.." group:"..group)
	end	for _, v in ipairs(MapEx[map_id].collect[group]) do
			lenCollect = lenCollect + 1
			list_collect[lenCollect] = list_collect[lenCollect] or {}
			list_collect[lenCollect].collect_id = v[1]
			list_collect[lenCollect].x = v[2]
			list_collect[lenCollect].y = v[3]
	end
	for _, v in pairs(Obj.scenes[scene_id]) do
		if v.collect_id and v.group == group then
			for i = lenCollect, 1, -1 do
				local m = list_collect[i]
				if m.collect_id == v.collect_id and m.x == v.born_x and m.y == v.born_y then
					list_collect[lenCollect], list_collect[i] = list_collect[i], list_collect[lenCollect]
					lenCollect = lenCollect - 1
					break
				end
			end
		end
	end

	for i = 1, lenCollect do
		local v = list_collect[i]
		--if Obj.areaHasHuman(scene_id, v.x, v.y) then
			local collect = ObjCollect.create(v.collect_id)
			collect.group = group
			ObjCollect.enterScene(collect, scene_id, v.x, v.y)
		--end
	end
end

function action.new_collect_group_fix(group)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]

	for _, v in ipairs(MapEx[map_id].collect[group]) do
		local collect = ObjCollect.create(v[1])
		ObjCollect.enterScene(collect, scene_id, v[2], v[3])	
	end
end

function action.new_monster(area_id, cap, monster_tb, cap_per)
	--[[if not condition.area_has_human(area_id) then
		return
	end--]]
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local sum = 0
	if Obj.scenes[data.scene_id] then
		for _, v in pairs(Obj.scenes[data.scene_id]) do
			if v.monster_id and v.area_id == area_id then
				sum = sum + 1
				if cap <= sum then
					return
				end
			end
		end
	end
	local list_rect = Map.getRects(map_id, area_id)
	if not cap_per or cap_per < 1 then
		cap_per = 0x7fffffff
	end
	for i = 1, math.min(cap - sum, cap_per) do
		local monster_id = monster_tb[math.random(1, #monster_tb)]
		local monster = ObjMonster.create(monster_id)
		local rect = list_rect[math.random(1, #list_rect)]
		monster.area_id = area_id
		ObjMonster.enterScene(monster, data.scene_id, math.random(rect[1], rect[3]), math.random(rect[2], rect[4]))
	end
end

function action.new_monster_fix(area_id, cap, monster_tb)
	local sum = 0
	if Obj.scenes[data.scene_id] then
		for _ in pairs(Obj.scenes[data.scene_id]) do
			sum = sum + 1
		end
	end
	if 1024 < sum then
		print(sum .. " objs in one scene")
		return
	end
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	for i = 1, cap do
		for j = 1, #list_rect do
			local monster_id = monster_tb[math.random(1, #monster_tb)]
			local monster = ObjMonster.create(monster_id)
			local rect = list_rect[j]
			ObjMonster.enterScene(monster, data.scene_id, math.random(rect[1], rect[3]), math.random(rect[2], rect[4]))
		end
	end
end

function add_reborn_time(monster)
  if not monster.need_reborn or not monster.area_id then
      return
  end  
  reborn_monster_die_time[monster.scene_id] = reborn_monster_die_time[monster.scene_id] or {}
  reborn_monster_die_time[monster.scene_id][monster.area_id] = reborn_monster_die_time[monster.scene_id][monster.area_id] or {}
  reborn_monster_die_time[monster.scene_id][monster.area_id][monster.monster_id] = Timer.now
end
-- 刷隔多久重生的怪(1只怪)
function action.monster_reborn(area_id, monster_id, reborn_time)
  local sum = 0
  if Obj.scenes[data.scene_id] then
    for _, v in pairs(Obj.scenes[data.scene_id]) do
      sum = sum + 1
      if v.monster_id  == monster_id and v.need_reborn and v.area_id == area_id then
          return 
      end
    end
  end
  if 1024 < sum then
    print(sum .. " objs in one scene")
    return
  end
  reborn_monster_die_time[data.scene_id] = reborn_monster_die_time[data.scene_id] or {}
  reborn_monster_die_time[data.scene_id][area_id] = reborn_monster_die_time[data.scene_id][area_id] or {}
  if reborn_monster_die_time[data.scene_id][area_id][monster_id] and reborn_monster_die_time[data.scene_id][area_id][monster_id] + reborn_time > Timer.now then
     return   --时间未到
  end
  local map_id = Map.scene_id_to_map_id[data.scene_id]
  local list_rect = Map.getRects(map_id, area_id)
  local monster = ObjMonster.create(monster_id)
  local rect = list_rect[1]
  monster.area_id = area_id
  monster.need_reborn = true
  ObjMonster.enterScene(monster, data.scene_id, math.random(rect[1], rect[3]), math.random(rect[2], rect[4]))     
end

local list_human = {}
function action.new_monster_group(group)
	local scene_id = data.scene_id
	local list_human_len = 0
	local map_id = Map.scene_id_to_map_id[scene_id]
	if not Map.list_monster[map_id] then
		assert(nil, map_id)
	end
	local list_monster = Map.list_monster[map_id][group]
	for _, v in pairs(Obj.scenes[scene_id]) do
		if v.obj_type == Obj.TYPE_HUMAN then
			list_human_len = list_human_len + 1
			list_human[list_human_len] = v
		end
		if v.monster_id and v.group == group then
			list_monster[v.born_x][v.born_y] = -list_monster[v.born_x][v.born_y]
		end
	end
	for x, t in pairs(list_monster) do
		for y, monster_id in pairs(t) do
			if monster_id < 0 then
				t[y] = -monster_id
			else
				for i = 1, list_human_len do
					local human = list_human[i]
					local dx = x - human.x
					local dy = y - human.y
					local r = 2048
					if -r < dx and dx < r and -r < dy and dy < r then
						local monster = ObjMonster.create(monster_id)
						monster.group = group
						ObjMonster.enterScene(monster, scene_id, x, y)
						break
					end
				end
			end
		end
	end
end

function action.new_monster_group_fix(group)
	local sum = 0
	if Obj.scenes[data.scene_id] then
		for _ in pairs(Obj.scenes[data.scene_id]) do
			sum = sum + 1
		end	
	end
	if 1024 < sum then
		print(sum .. " objs in one scene".. Map.scene_id_to_map_id[data.scene_id])
		return
	end
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	if Map.list_monster[map_id] then
		if not Map.list_monster[map_id][group] then
			assert(nil, "map_id:"..map_id.." group:"..group)
		end
		for x, t in pairs(Map.list_monster[map_id][group]) do
			for y, monster_id in pairs(t) do
				local monster = ObjMonster.create(monster_id)
				monster.group = group
				ObjMonster.enterScene(monster, scene_id, x, y)
			end
		end
	end
end

function action.new_monster_x_y(monster_id)
	if Obj.scenes[data.scene_id] then
		local monster = ObjMonster.create(monster_id)
		ObjMonster.enterScene(monster, data.scene_id, data.x, data.y)
	end
end

function action.new_npc_group(group, body_id, way)
	if group < 1 then
		assert()
	end
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	for _, v in ipairs(MapEx[map_id].npc[group]) do
		if body_id then
			local mm = Msg.gc.GC_SHOW_DISPLAY
			mm.body_id = body_id
			mm.x = v[2]
			mm.y = v[3]
			mm.effectConfig = EffectLogic.getConfig(mm.body_id)
			Obj.sendArea(mm, scene_id, v[2], v[3])
		end
		local npc = ObjNpc.create(v[1])
		if way then
			local mm = Msg.gc.GC_BEFORE_OBJ_APPEAR
			mm.obj_id = npc.id
			mm.cmd = way
			Obj.sendArea(mm, npc.scene_id, v[2], v[3])
		end
		Obj.enterScene(npc, data.scene_id, v[2], v[3])
	end
end

function action.npc_talk(npc_id, talk_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.npc_id == npc_id then
			local mm = Msg.gc.GC_OBJ_TALK
			mm.obj_id = v.id
			mm.txt = ExcelMapConf.txt[talk_id].txt
			Obj.sendArea(mm, data.scene_id, v.x, v.y)
			return
		end
	end
	for k, v in ipairs(Map.list_gc_add_obj[Map.scene_id_to_map_id[data.scene_id]].npc) do
		if v.npc_id == npc_id then
			local mm = Msg.gc.GC_OBJ_TALK
			mm.obj_id = v.obj_id
			mm.txt = ExcelMapConf.txt[talk_id].txt
			Obj.sendArea(mm, data.scene_id, v.x, v.y)
			return
		end
	end
end

function action.ref_map(ai_id, cnt)
	if type(ai_id) == "number" then
		doSceneEvent(data.scene_id, ai_id)
	else
		cnt = cnt or 1
		for i = 1, #ai_id do
			local j = math.random(1, #ai_id)
			ai_id[i], ai_id[j] = ai_id[j], ai_id[i]
		end
		for i = 1, cnt do
			doSceneEvent(data.scene_id, ai_id[i])
		end
	end
end

function action.ref_monster(monster_id, ai_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.monster_id == monster_id and 0 < v.hp then
			v.ref_ai_id = ai_id
		end
	end
end

function action.revive_all_human()
	for _, human in pairs(Obj.scenes[data.scene_id]) do
		if human.obj_type == Obj.TYPE_HUMAN and human.db.hp < 1 then
			RoleRevive.reviveGoHome(human, true)
		end
	end
end

function action.script(script_id)
	local mm = Msg.gc.GC_SCRIPT_START
	mm.script_id = script_id
	mm.delay = 0
	Obj.sendScene(mm, data.scene_id)
end

function action.set_n(str)
	local scene_id = data.scene_id
	n[scene_id] = n[scene_id] or 0
	local fun
	if action_set_n[str] then
		fun = action_set_n[str]
	else
		fun = load("return function(n)return " .. str .. " end")()
		action_set_n[str] = fun
	end
	n[scene_id] = fun(n[scene_id])
	CopyCallback.onSceneNChange(scene_id)
end

function action.shortcut(pos)
	local mm = Msg.gc.GC_ROLE_SHORTCUT
	mm.pos = pos
	Obj.sendScene(mm, data.scene_id)
end

function action.show_txt(txt_id, area_id, r)
	local mm = Msg.gc.GC_SHOW_TXT
	mm.txt = ExcelMapConf.txt[txt_id].txt
	if area_id then
		local scene_id = data.scene_id
		local rect = Map.getRects(Map.scene_id_to_map_id[scene_id], area_id)[1]
		if r then
			_G.lua_aoi.send_area(Obj.scenes_fds[scene_id], (rect[1] + rect[3]) / 2, (rect[2] + rect[4]) / 2, nil, r, r, mm)
		else
			Obj.sendArea(mm, scene_id, (rect[1] + rect[3]) / 2, (rect[2] + rect[4]) / 2)
		end
	else
		Obj.sendScene(mm, data.scene_id)
	end
end

function action.show_txt_world(txt_id)	
	Broadcast.sendBroadcast2World(Lang.GROSSIP+Lang.UP, ExcelMapConf.txt[txt_id].txt)
end

function action.skill(area_id, tb_skill_id, target_type, atk)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	local objSkill = ObjSkill.getObjSkill(atk)
	objSkill.scene_id = scene_id
	objSkill.target_type = target_type
	for i = 1, #list_rect do
		local x = (list_rect[i][1] + list_rect[i][3]) / 2
		local y = (list_rect[i][2] + list_rect[i][4]) / 2
		objSkill.x = x
		objSkill.y = y
		Skill.add(objSkill, tb_skill_id[math.random(1, #tb_skill_id)], x, y, x, y, nil, 1, true)
	end
end

function action.skill_rand(area_id, tb_skill_id, target_type, atk)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	local objSkill = ObjSkill.getObjSkill(atk)
	objSkill.scene_id = scene_id
	objSkill.target_type = target_type
	for i = 1, #list_rect do
		local x = math.random(list_rect[i][1], list_rect[i][3])
		local y = math.random(list_rect[i][2], list_rect[i][4])	
		objSkill.x = x
		objSkill.y = y
		Skill.add(objSkill, tb_skill_id[math.random(1, #tb_skill_id)], x, y, x, y, nil, 1, true)
	end
end

function action.skill_two_area(area_id_a, area_id_b, tb_skill_id, target_type, atk)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	local list_rect = Map.getRects(map_id, area_id_a)
	local list_rect2 = Map.getRects(map_id, area_id_b)
	local objSkill = ObjSkill.getObjSkill(atk)
	objSkill.scene_id = scene_id
	objSkill.target_type = target_type
	if #list_rect < #list_rect2 then
		local x = (list_rect[1][1] + list_rect[1][3]) / 2
		local y = (list_rect[1][2] + list_rect[1][4]) / 2
		objSkill.x = x
		objSkill.y = y
		for _, v in ipairs(list_rect2) do
			Skill.add(objSkill, tb_skill_id[math.random(1, #tb_skill_id)], (v[1] + v[3]) / 2, (v[2] + v[4]) / 2, x, y, nil, 1, true)
		end
	else
		local tx = (list_rect2[1][1] + list_rect2[1][3]) / 2
		local ty = (list_rect2[1][2] + list_rect2[1][4]) / 2
		for _, v in ipairs(list_rect) do
			local x = (v[1] + v[3]) / 2
			local y = (v[2] + v[4]) / 2
			objSkill.x = x
			objSkill.y = y
			Skill.add(ObjSkill.getObjSkill(atk), tb_skill_id[math.random(1, #tb_skill_id)], tx, ty, x, y, nil, 1, true)
		end
	end
end

function action.sleep(sec)
	wake_up_time[data.scene_id] = sec * 1000 + Timer.now
end

function action.tip_use_item(item_list)
	local scene_id = data.scene_id
	for _, v in pairs(Obj.scenes_fds[scene_id]) do
		if 0 < v.db.hp and v.tip_use_item_scene_id ~= item_list then
			for _, vv in ipairs(item_list) do
				local cmd = ExcelItem.item[vv].command
				if cmd[1] == "buf" and Buffer.hasBuf(v, cmd[2]) then
					v.tip_use_item_scene_id = item_list
					break
				end
				for kkk, vvv in pairs(v.db.bag) do
					if 0 < kkk and vvv.id == vv then
						v.tip_use_item_scene_id = item_list
						local mm = Msg.gc.GC_TIP_USE_ITEM
						mm.pos_in_bag = kkk
						Msg.send(mm, v.fd)
						break
					end
				end
				if v.tip_use_item_scene_id == item_list then
					break
				end
			end
		end
	end
end

function action.touxiang_talk(icon, talk_id)
	local mm = Msg.gc.GC_MARRY_NPC_INFO
	mm.info = ExcelMapConf.txt[talk_id].txt
	mm.icon = icon
	Obj.sendScene(mm, data.scene_id)
end

function action.transfer_scene_to_area(area_id, sex, except)
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	local rect = list_rect[1]
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.obj_type == Obj.TYPE_HUMAN and (not sex or sex == 0 or sex == v.db.sex) and (not except or not Map.is_in_area_id(map_id, v.x, v.y, except)) then
			Obj.jump(v, math.random(rect[1], rect[3]), math.random(rect[2], rect[4]), Msg.gc.GC_JUMP)
			local pet = Obj.getObj(v.fight_pet_id, v.fight_pet_uid)
			if pet then
				Obj.jump(pet, math.random(rect[1], rect[3]), math.random(rect[2], rect[4]), Msg.gc.GC_JUMP)
			end
		end
	end
end

function action.wave(is_start)
	local mm = Msg.gc.GC_WAVE
	mm.is_start = is_start
	Obj.sendScene(mm, data.scene_id)
end

function action.kick_allhuman_to_premap()
    local nSceneID = data.scene_id
    if Obj.scenes[nSceneID] then
        for _, v in pairs(Obj.scenes[nSceneID]) do
            if v.obj_type == Obj.TYPE_HUMAN then
                local nPreMapID = v.db.preMapID
                local nPreMapX = v.db.preMapX
                local nPreMapY = v.db.preMapY
                ObjHuman.enterMap(v, nPreMapID, nPreMapX, nPreMapY)
            end
        end
    end
end

function action.pata()
  Pata.ref_scene_event(data.scene_id)
end

function condition.all_monster_die(except_monster_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.monster_id and 0 < v.hp and (not v.owner and ObjMonster.getValue(v, "camps") == "enemy" or Obj.getOwner(v) and Obj.getOwner(v).monster_id and ObjMonster.getValue(Obj.getOwner(v), "camps") == "enemy") then	
			local ac
			if except_monster_id then
				for _, vv in ipairs(except_monster_id) do
					if v.monster_id == vv then 
						ac = true
						break
					end
				end
			end
			if not ac then
				return
			end
		end
	end
	return true
end

function condition.area_has_collect(area_id)
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.collect_id then
			for i = 1, #list_rect do
				local rect = list_rect[i]
				local min_x = rect[1]
				local min_y = rect[2]
				local max_x = rect[3]
				local max_y = rect[4]
				if min_x < v.x and v.x < max_x and min_y < v.y and v.y < max_y then	
					return true
				end
			end
		end
	end
end

function condition.area_has_collect_id(area_id, collect_id)
	if not collect_id then
		assert()
	end
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.collect_id == collect_id then
			for i = 1, #list_rect do
				local rect = list_rect[i]
				local min_x = rect[1]
				local min_y = rect[2]
				local max_x = rect[3]
				local max_y = rect[4]
				if min_x < v.x and v.x < max_x and min_y < v.y and v.y < max_y then	
					return true
				end
			end
		end
	end
end

function condition.area_has_display(area_id)
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.obj_type == Obj.TYPE_DISPLAY then
			for _, rect in ipairs(list_rect) do
				if rect[1] < v.x and v.x < rect[3] and rect[2] < v.y and v.y < rect[4] then	
					return true
				end
			end
		end
	end
end
function condition.area_has_human(area_id, cnt)
	cnt = cnt or 1
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	local sum = 0
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.obj_type == Obj.TYPE_HUMAN and not v.hide then
			for i = 1, #list_rect do
				local rect = list_rect[i]
				local min_x = rect[1]
				local min_y = rect[2]
				local max_x = rect[3]
				local max_y = rect[4]
				if min_x < v.x and v.x < max_x and min_y < v.y and v.y < max_y then
					sum = sum + 1
					if cnt <= sum then
						return true
					end
				end
			end
		end
	end
end

function condition.area_has_human_live(area_id, cnt)
	cnt = cnt or 1
	--print("area_has_human", area_id)
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	local sum = 0
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.obj_type == Obj.TYPE_HUMAN and 0 < v.db.hp then
			for i = 1, #list_rect do
				local rect = list_rect[i]
				local min_x = rect[1]
				local min_y = rect[2]
				local max_x = rect[3]
				local max_y = rect[4]
				if min_x < v.x and v.x < max_x and min_y < v.y and v.y < max_y then
					sum = sum + 1
					if cnt <= sum then
						return true
					end
				end
			end
		end
	end
end

function condition.area_has_monster(area_id)
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.obj_type == Obj.TYPE_MONSTER and 0 < v.hp then
			for i = 1, #list_rect do
				local rect = list_rect[i]
				local min_x = rect[1]
				local min_y = rect[2]
				local max_x = rect[3]
				local max_y = rect[4]
				if min_x < v.x and v.x < max_x and min_y < v.y and v.y < max_y then	
					return true
				end
			end
		end
	end
end

function condition.area_has_monster_id(area_id, monster_id)
	local map_id = Map.scene_id_to_map_id[data.scene_id]
	local list_rect = Map.getRects(map_id, area_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.monster_id == monster_id and 0 < v.hp then
			for i = 1, #list_rect do
				local rect = list_rect[i]
				local min_x = rect[1]
				local min_y = rect[2]
				local max_x = rect[3]
				local max_y = rect[4]
				if min_x < v.x and v.x < max_x and min_y < v.y and v.y < max_y then	
					return true
				end
			end
		end
	end
end

function condition.area_has_sex(area_id, sex)
	local list_rect = Map.getRects(Map.scene_id_to_map_id[data.scene_id], area_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.db and v.db.sex == sex then
			for i = 1, #list_rect do
				local rect = list_rect[i]
				if rect[1] < v.x and v.x < rect[3] and rect[2] < v.y and v.y < rect[4] then
					return true
				end
			end
		end
	end
end

function condition.check_n(str)
	local scene_id = data.scene_id
	n[scene_id] = n[scene_id] or 0
	local fun
	if condition_check_n[str] then
		fun = condition_check_n[str]
	else
		fun = load("return function(n)return " .. str .. " end")()
		condition_check_n[str] = fun
	end
	return fun(n[scene_id])
end

function condition.create_time_over(t)
	return t * 1000 <= Timer.now - create_time[data.scene_id]
end

local timeTb = {hour = 0, min = 0, sec = 0}
function condition.date_before(year, month, day)
	timeTb.year = assert(year)
	timeTb.month = assert(month)
	timeTb.day = assert(day)
	return os.time() < os.time(timeTb)
end

function condition.finish_recur(ai_id, sec)
	local scene_id = data.scene_id
	local cur_ai = data.cur_ai
	return event_cnt[scene_id] and event_cnt[scene_id][ai_id] and (not event_cnt[scene_id][cur_ai] or event_cnt[scene_id][cur_ai] < event_cnt[scene_id][ai_id]) and sec * 1000 < Timer.now - event_time[scene_id][ai_id]
end

function condition.finish_simple(ai_id, sec)
	local scene_id = data.scene_id
	local map_id = Map.scene_id_to_map_id[scene_id]
	--[[if event_cnt[scene_id] and event_cnt[scene_id][ai_id] then
		print( ExcelMapConf[map_id][ai_id].cnt, " ExcelMapConf[map_id][ai_id].cnt")
		print(event_cnt[scene_id][ai_id], "event_cnt[scene_id][ai_id]")
		print(sec, "sec")
		print(ai_id, "ai_id")
		print(data.cur_ai, "cur")
	end--]]
	if not sec then sec = 1 end
	return event_cnt[scene_id] and event_cnt[scene_id][ai_id] and ExcelMapConf[map_id][ai_id].cnt <= event_cnt[scene_id][ai_id] and sec * 1000 <= Timer.now - event_time[scene_id][ai_id]
end

function condition.hour(a, b)
	local h = os.date("%H", os.time()) + 0
	return a <= h and h < b
end

function condition.is_middle()
	return Config.IS_MIDDLE
end

function condition.is_open_middle()
	return Config.OPEN_MIDDLE
end
function condition.map_has_collect_id(collect_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.collect_id == collect_id then	
			return true
		end
	end
end

function condition.map_has_monster_group_id(group)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.obj_type == Obj.TYPE_MONSTER then
			if v.group == group and 0 < v.hp then	
				return true
			end
		end
	end
end

function condition.map_has_monster_id(monster_id)
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.monster_id == monster_id and 0 < v.hp then	
			return true
		end
	end
end

function condition.map_monster_cnt_lt(cnt)
	local sum = 0
	for _, v in pairs(Obj.scenes[data.scene_id]) do
		if v.monster_id then
			sum = sum + 1
			if cnt <= sum then
				return
			end
		end
	end
	return true
end

function condition.minute(a, b)
	local m = os.date("%M", os.time()) + 0
	return a <= m and m < b
end

function condition.orr(a, b)
	return condition[a[1]](a[2], a[3], a[4], a[5]) or condition[b[1]](b[2], b[3], b[4], b[5])
end

function condition.rand(sum)
	return math.random(1, 100) <= sum
end

function condition.rand_cd(sum)
	local tmp = math.random(1, 100) <= sum
	if not tmp then
		local scene_id = data.scene_id
		local ai = data.cur_ai
		event_cnt[scene_id] = event_cnt[scene_id] or {}
		event_time[scene_id] = event_time[scene_id] or {}
		event_cnt[scene_id][ai] = (event_cnt[scene_id][ai] or 0) + 1
		event_time[scene_id][ai] = Timer.now
	end
	return tmp
end

function condition.script_has_stop(script_id)
  local copyID = Copy.sceneID2CopyID[data.scene_id]
  local roomID = Copy.sceneID2Room[data.scene_id]
  if copyID and roomID then
      if Copy.room2Script[copyID] and Copy.room2Script[copyID][roomID] then
          return Copy.room2Script[copyID][roomID][script_id]
      end
      return
  end
end

local tb = {}
for k, v in pairs(condition) do
	tb["not_" .. k] = function(a, b) return not v(a, b) end
end
for k, v in pairs(tb) do
	condition[k] = v
end

function finish_ai(scene_id, aiID)
  data.scene_id = scene_id
  if condition.finish_simple(aiID) then
      return
  end
  local map_id = Map.scene_id_to_map_id[scene_id]
  local aiInfo = ExcelMapConf[map_id][aiID]
  if not aiInfo then
    assert(nil, map_id .. " " .. aiID)
  end
  create_time[scene_id] = create_time[scene_id] or Timer.now
  data.scene_id = scene_id
  event_cnt[scene_id] = event_cnt[scene_id] or {}
  event_time[scene_id] = event_time[scene_id] or {}
  event_cnt[scene_id][aiID] = (event_cnt[scene_id][aiID] or 0) + 1
  event_time[scene_id][aiID] = Timer.now
end

function doSceneEvent(scene_id, aiID)
	local map_id = Map.scene_id_to_map_id[scene_id]
	local aiInfo = ExcelMapConf[map_id][aiID]
	if not aiInfo then
		assert(nil, map_id .. " " .. aiID)
	end
	create_time[scene_id] = create_time[scene_id] or Timer.now
	data.scene_id = scene_id
	data.cur_ai = aiID
	if	not event_cnt[scene_id] or
		not event_time[scene_id] or
		not event_cnt[scene_id][aiID] or
		not event_time[scene_id][aiID] or
		(aiInfo.cnt == 0 or event_cnt[scene_id][aiID] < aiInfo.cnt) and aiInfo.cd * 1000 <= Timer.now - event_time[scene_id][aiID] then
		if	(aiInfo.condition_cmd1 == "" or condition[aiInfo.condition_cmd1](aiInfo.condition_arg1[1], aiInfo.condition_arg1[2], aiInfo.condition_arg1[3], aiInfo.condition_arg1[4])) and
			(aiInfo.condition_cmd2 == "" or condition[aiInfo.condition_cmd2](aiInfo.condition_arg2[1], aiInfo.condition_arg2[2], aiInfo.condition_arg2[3], aiInfo.condition_arg2[4])) and
			(aiInfo.condition_cmd3 == "" or condition[aiInfo.condition_cmd3](aiInfo.condition_arg3[1], aiInfo.condition_arg3[2], aiInfo.condition_arg3[3], aiInfo.condition_arg3[4])) and
			(aiInfo.condition_cmd4 == "" or condition[aiInfo.condition_cmd4](aiInfo.condition_arg4[1], aiInfo.condition_arg4[2], aiInfo.condition_arg4[3], aiInfo.condition_arg4[4])) and
			(aiInfo.condition_cmd5 == "" or condition[aiInfo.condition_cmd5](aiInfo.condition_arg5[1], aiInfo.condition_arg5[2], aiInfo.condition_arg5[3], aiInfo.condition_arg5[4])) then
			event_cnt[scene_id] = event_cnt[scene_id] or {}
			event_time[scene_id] = event_time[scene_id] or {}
			event_cnt[scene_id][aiID] = (event_cnt[scene_id][aiID] or 0) + 1
			event_time[scene_id][aiID] = Timer.now
			if aiInfo.action_cmd1 ~= "" then
				if not action[aiInfo.action_cmd1] then
					assert(nil, aiInfo.action_cmd1)
				end
				action[aiInfo.action_cmd1](aiInfo.action_arg1[1], aiInfo.action_arg1[2], aiInfo.action_arg1[3], aiInfo.action_arg1[4], aiInfo.action_arg1[5], aiInfo.action_arg1[6], aiInfo.action_arg1[7], aiInfo.action_arg1[8])
			end
			if aiInfo.action_cmd2 ~= "" then
				if not action[aiInfo.action_cmd2] then
					assert(nil, aiInfo.action_cmd2)
				end
				action[aiInfo.action_cmd2](aiInfo.action_arg2[1], aiInfo.action_arg2[2], aiInfo.action_arg2[3], aiInfo.action_arg2[4], aiInfo.action_arg2[5], aiInfo.action_arg2[6], aiInfo.action_arg2[7], aiInfo.action_arg2[8])
			end
			if aiInfo.action_cmd3 ~= "" then
				if not action[aiInfo.action_cmd3] then
					assert(nil, aiInfo.action_cmd3)
				end
				action[aiInfo.action_cmd3](aiInfo.action_arg3[1], aiInfo.action_arg3[2], aiInfo.action_arg3[3], aiInfo.action_arg3[4], aiInfo.action_arg3[5], aiInfo.action_arg3[6], aiInfo.action_arg3[7], aiInfo.action_arg3[8])
			end
			if aiInfo.action_cmd4 ~= "" then
				action[aiInfo.action_cmd4](aiInfo.action_arg4[1], aiInfo.action_arg4[2], aiInfo.action_arg4[3], aiInfo.action_arg4[4], aiInfo.action_arg4[5], aiInfo.action_arg4[6], aiInfo.action_arg4[7], aiInfo.action_arg4[8])
			end
			if aiInfo.action_cmd5 ~= "" then
				action[aiInfo.action_cmd5](aiInfo.action_arg5[1], aiInfo.action_arg5[2], aiInfo.action_arg5[3], aiInfo.action_arg5[4], aiInfo.action_arg5[5], aiInfo.action_arg5[6], aiInfo.action_arg5[7], aiInfo.action_arg5[8])
			end
		end
	end
end

function ai(scene_id)
	if wake_up_time[scene_id] and Timer.now < wake_up_time[scene_id] then
		--print("sleep ")
		return
	end
	do_ai_by_callback(scene_id, "before_time")
	do_ai_by_callback(scene_id, "time")
end

function do_ai_by_callback(scene_id, cb)
	local map_id = Map.scene_id_to_map_id[scene_id]
	assert(ExcelMapConf[map_id], map_id)
	for k, v in pairs(ExcelMapConf[map_id]) do
		if v.callback == cb then
			doSceneEvent(scene_id, k)
		end
	end
end

function sceneClear(scene_id)	
	sceneRst(scene_id)
	if Obj.scenes[scene_id] then
		for _, v in pairs(Obj.scenes[scene_id]) do
			Obj.destroyAllType(v)
		end	
		Obj.scenes[scene_id] = nil
		Obj.scenes_fds[scene_id] = nil
	end
	create_time[scene_id] = nil
end

function sceneClearExcepteHumanAndNpc(scene_id)
	sceneRst(scene_id)
	if Obj.scenes[scene_id] then
		for _, v in pairs(Obj.scenes[scene_id]) do
			if v.obj_type ~= Obj.TYPE_HUMAN and v.obj_type ~= Obj.TYPE_NPC and v.obj_type ~= Obj.TYPE_PET and not v.pet_id and (not v.monster_id or 0 < v.hp) then
				Obj.destroyAllType(v)
			end
		end
	end
	wake_up_time[scene_id] = Timer.now * 2
end

function sceneRst(scene_id)
	event_cnt[scene_id] = nil
	event_time[scene_id] = nil
	n[scene_id] = nil
	ban[scene_id] = nil
	wake_up_time[scene_id] = nil
	piaohua[scene_id] = nil
	reborn_monster_die_time[scene_id] = nil
end

function setBan(scene_id)
	map_mgr.dynamic_block_vis()
	local list = ban[scene_id]
	if list then
		local map_id = Map.scene_id_to_map_id[scene_id]
		for _, area_id in ipairs(list) do
			local list_rect = Map.getRects(map_id, area_id)
			for i = 1, #list_rect do
				local right = list_rect[i]
				map_mgr.dynamic_block_set(right[1], right[2], right[3], right[4])
			end
		end
	end
end
